package com.反射;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class Person {
  private String name;
  private int age;
  private int height = 180;

  public Person(String name, int age) {
    this.name = name;
    this.age = age;
  }

  public Person() {}

  public Person(String name, int age, int height) {
    this.name = name;
    this.age = age;
    this.height = height;
  }

  public String getName() {
    return name;
  }

  public void setName(String name) {
    this.name = name;
  }

  public int getAge() {
    return age;
  }

  public void setAge(int age) {
    this.age = age;
  }

  @Override
  public String toString() {
    return "Person{" +
            "name='" + name + '\'' +
            ", age=" + age +
            ", height=" + height +
            '}';
  }

  public static void main(String[] args) throws Exception {
    //    Person person = new Person("张三",10);
    //    System.out.println(person.getClass());
    //    System.out.println(person.getClass().getName());
    //    String s = "com.反射.Person";
    //    try {
    //      System.out.println(Class.forName(s)); //class com.反射.Person
    //    } catch (ClassNotFoundException e) {
    //      e.printStackTrace();
    //    }

    //    Class p1 = Person.class;
    //    System.out.println(p1);  //class com.反射.Person

//    Class person = Class.forName("com.反射.Person");
//    Constructor constructor = person.getConstructor();
//    Person p1 = (Person) constructor.newInstance();
//    System.out.println(p1); //Person{name='null', age=0} 无参构造方法；

    /**
     * 通过反射动态调用方法；
     */
    Class clazz = Class.forName("com.反射.Person");
    Constructor c  = clazz.getDeclaredConstructor(String.class,int.class,int.class);
    Person person = (Person) c.newInstance("张三",18,100);
    System.out.println(person); // Person{name='张三', age=18, height=100}
    Method m = clazz.getMethod("setName", String.class);
    m.invoke(person,"李四"); // 通过反射动态的调用setName方法
    System.out.println(person); //Person{name='李四', age=18, height=100}

    Field f = clazz.getDeclaredField("age");
    f.setAccessible(true); // 解开安全锁，表示这个属性可以访问
    f.set(person,30);
    System.out.println(person);

//    Class person1 = Person.class;
//    Constructor constructor1 = person1.getConstructor(String.class,int.class);
//    Person p2 = (Person)constructor1.newInstance("张三",19);
//    System.out.println(p2); //Person{name='张三', age=19} 带两个参数的构造方法
//
//
//    Class person2 = Class.forName("com.反射.Person");
//    Constructor constructor2 = person2.getConstructor(String.class,int.class,int.class);
//    Person p3 = (Person) constructor2.newInstance("李四",20,170);
//    System.out.println(p3); // Person{name='李四', age=20, height=170}





  }
}
